import org.junit.Test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 35326
 * 2021/3/25 8:55
 * ReentrantLock的使用测试
 */
public class ReentrantLockTest implements Runnable {
	@Override
	public void run() {
		try {
			if(lock==1){
				lock1.lockInterruptibly();
				try{
					Thread.sleep(500);
				}catch (InterruptedException e){

				}
				lock2.lockInterruptibly();
			}else{
				lock2.lockInterruptibly();
				try{
					Thread.sleep(500);
				}catch (InterruptedException e){

				}
				lock1.lockInterruptibly();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			if(lock1.isHeldByCurrentThread()){
				lock1.unlock();
			}
			if(lock2.isHeldByCurrentThread()){
				lock2.unlock();
			}
			System.out.println(Thread.currentThread().getName()+"线程退出");
		}

	}

	public static ReentrantLock lock1 = new ReentrantLock();
	public static ReentrantLock lock2 = new ReentrantLock();
	int lock;

	public ReentrantLockTest(int lock){
		this.lock=lock;
	}

	public ReentrantLockTest(){

	}

	public static void main(String[] args) {
		ReentrantLockTest reentrantLockTest1=new ReentrantLockTest(1);
		ReentrantLockTest reentrantLockTest2=new ReentrantLockTest(2);
		Thread t1=new Thread(reentrantLockTest1);
		Thread t2=new Thread(reentrantLockTest2);
		t1.start();
		t2.start();
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		t1.interrupt();
	}

	@Test
	/**
	 * 测试可重入锁的tryLock()方法的使用
	 */
	public void testTryLock(){
	     TryLockThread tryLockThread = new TryLockThread();
	     Thread t1= new Thread(tryLockThread);
	     Thread t2=new Thread(tryLockThread);
	     t1.start();
	     t2.start();
	}



}

class TryLockThread implements Runnable{
	private static ReentrantLock lock = new ReentrantLock();
	@Override
	public void run() {
		try {
			if(lock.tryLock(4, TimeUnit.SECONDS)){
				try {
					Thread.sleep(6000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}else {
				System.out.println("get lock failed...");
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			if(lock.isHeldByCurrentThread()){
				lock.unlock();
			}
		}
	}
}


